package com.granada.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.granada.shiro.CustomAccessControlFilter;
import com.granada.shiro.CustomHashedCredentialsMatcher;
import com.granada.shiro.CustomRealm;
import com.granada.shiro.RedisCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @ClassName: ShiroConfig
 * TODO:类文件简单描述
 * @Author: 小霍
 * @CreateDate: 2019/9/7 13:31
 * @UpdateUser: 小霍
 * @UpdateDate: 2019/9/7 13:31
 * @Version: 0.0.1
 */
@Configuration
public class ShiroConfig {

    @Bean
    public CustomHashedCredentialsMatcher customHashedCredentialsMatcher(){
        return new CustomHashedCredentialsMatcher();
    }

    @Bean
    public CustomRealm customRealm(){
        CustomRealm customRealm=new CustomRealm();
        customRealm.setCredentialsMatcher(customHashedCredentialsMatcher());
        customRealm.setCacheManager(redisCacheManager());
        return customRealm;
    }

    @Bean
    public RedisCacheManager redisCacheManager(){
        return new RedisCacheManager();
    }


    @Bean
    public SecurityManager securityManager(){

        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(customRealm());
        return securityManager;
    }


    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //自定义拦截器限制并发人数,参考博客：
        LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>();
        //用来校验token
        filtersMap.put("token", new CustomAccessControlFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/sys/user/login", "anon");
        filterChainDefinitionMap.put("/sys/user/token", "anon");
        filterChainDefinitionMap.put("/index/**", "anon");
        filterChainDefinitionMap.put("/api/**", "anon");
        filterChainDefinitionMap.put("/temp/**", "anon");
        filterChainDefinitionMap.put("*.html", "anon");
        filterChainDefinitionMap.put("/app/login/register", "anon");  //APP注册
        filterChainDefinitionMap.put("/app/login/applogin", "anon"); //APP登录
        filterChainDefinitionMap.put("/app/login/vaildCode", "anon"); //获取手机验证码
        filterChainDefinitionMap.put("/app/login/phone", "anon"); //忘记密码
        filterChainDefinitionMap.put("/api/login/code", "anon"); //获取code
        filterChainDefinitionMap.put("/api/login/phone", "anon"); //获取手机号
        filterChainDefinitionMap.put("/api/login/register", "anon"); //微信注册
        filterChainDefinitionMap.put("/api/login/decrypt", "anon"); //微信注册
        filterChainDefinitionMap.put("/app/manufactor/login", "anon"); //微信注册
        filterChainDefinitionMap.put("/app/channe/list", "anon"); //了解途径
        //上传路径权限过滤
        filterChainDefinitionMap.put("/pc/parts/uploadImg", "anon"); //上传
        filterChainDefinitionMap.put("/pc/pingequipment/parts", "anon"); //配件列表
        filterChainDefinitionMap.put("/pcfuwuRepair/service/Addrepair", "anon"); //PC端新增报修
        filterChainDefinitionMap.put("/pcfuwuRepair/service/addcontextRepairs", "anon"); //PC端新增报修

        //上传路径权限过滤
        filterChainDefinitionMap.put("/pcfuwu/service/uploadImg", "anon"); //上传

        //放开swagger-ui地址
        //filterChainDefinitionMap.put("/swagger/**", "anon");
        filterChainDefinitionMap.put("/doc.html", "anon");
        filterChainDefinitionMap.put("/v2/api-docs", "anon");
        //filterChainDefinitionMap.put("/swagger-ui.html", "anon");
        filterChainDefinitionMap.put("/swagger-resources/**", "anon");
        filterChainDefinitionMap.put("/apple-app-site-association/**", "anon");//配置ios唤醒app文件
        filterChainDefinitionMap.put("/webjars/**", "anon");
        filterChainDefinitionMap.put("/druid/**", "anon");
        filterChainDefinitionMap.put("/favicon.ico", "anon");
        filterChainDefinitionMap.put("/captcha.jpg", "anon");
        filterChainDefinitionMap.put("/","user");
        filterChainDefinitionMap.put("/csrf","anon");
        filterChainDefinitionMap.put("/images/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/layui/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/treetable-lay/**", "anon");
        filterChainDefinitionMap.put("/**","token,authc");
        shiroFilterFactoryBean.setLoginUrl("/index/login");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 开启shiro aop注解支持.
     * 使用代理方式;所以需要开启代码支持;
     * @Author:      小霍
     * @CreateDate:  2019/9/19 10:50
     * @UpdateUser:
     * @UpdateDate:  2019/9/19 10:50
     * @Version:     0.0.1
     * @param securityManager
     * @return       org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
     * @throws
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

}
